//
//  NSMutableArray+KLException.m
//  KoalaUtilKit
//
//  Created by Tommy on 15/1/29.
//  Copyright (c) 2015年 Koala Team. All rights reserved.
//

#import "NSMutableArray+KLException.h"
#import "KLLog.h"
#import "NSObject+KLSwizzle.h"


@implementation NSMutableArray (KLException)

#if KLENABLE_EXCEPTION_SWIZZLE

+ (void)load{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        Class cls = [[self arrayWithCapacity:0] class];
        [cls kl_swizzleInstanceSelector:@selector(objectAtIndex:) withNewSelector:KLHookedSel(objectAtIndex:)];
        [cls kl_swizzleInstanceSelector:@selector(setObject:atIndex:) withNewSelector:KLHookedSel(setObject:atIndex:)];
        [cls kl_swizzleInstanceSelector:@selector(insertObject:atIndex:) withNewSelector:KLHookedSel(insertObject:atIndex:)];                                                                               
        [cls kl_swizzleInstanceSelector:@selector(removeObjectAtIndex:) withNewSelector:KLHookedSel(removeObjectAtIndex:)];

    });
}

- (id)KLHookedMethod(objectAtIndex:(NSUInteger)index){
    __autoreleasing id instance = nil;
    if([self checkRange:index]){
        @try{
            instance = [self KLHookedMethod(objectAtIndex:index)];
        }
        @catch (NSException *exception) {
            NSAssert(0,@"exception:%@",exception);
            KLLogError(@"exception:%@",exception);
        }
    }else{
        NSAssert(0,@"catch out of range:%lul in %@ ",(unsigned long)index,self);
        KLLogError(@"catch out of range:%lul in %@ ",(unsigned long)index,self);
    }
    
    return instance;
}

- (void)KLHookedMethod(setObject:(id)object atIndex:(NSUInteger)index){
    if(object&&[self checkRange:index]){
        @try{
            [self KLHookedMethod(setObject:object atIndex:index)];
        }
        @catch (NSException *exception) {
            NSAssert(0,@"exception:%@",exception);
            KLLogError(@"exception:%@",exception);
        }
    }else{
        NSAssert(0,@"can't setObject nil at %lu to %@",(unsigned long)index,self);
        KLLogError(@"can't setObject nil at %lu to %@",(unsigned long)index,self);
    }
}
- (void)KLHookedMethod(insertObject:(id)object atIndex:(NSUInteger)index){

    if(object && (index <= [self count])){
        @try{
            [self KLHookedMethod(insertObject:(id)object atIndex:(NSUInteger)index)];
        }
        @catch (NSException *exception) {
            NSAssert(0,@"exception:%@",exception);
            KLLogError(@"exception:%@",exception);
        }
    }else{
        NSAssert(0,@"can't insert nil at %lu to %@",(unsigned long)index,self);
        KLLogError(@"can't insert nil at %lu to %@",(unsigned long)index,self);
    }

}

- (void)KLHookedMethod(removeObjectAtIndex:(NSUInteger)index){

    if([self checkRange:index]){
        @try{
            [self KLHookedMethod(removeObjectAtIndex:index)];
        }
        @catch (NSException *exception) {
            NSAssert(0,@"exception:%@",exception);
            KLLogError(@"exception:%@",exception);
        }
    }else{
        NSAssert(0,@"catch out of range:%lul in %@ ",(unsigned long)index,self);
        KLLogError(@"catch out of range:%lul in %@ ",(unsigned long)index,self);
    }
    

}

- (BOOL)checkRange:(NSUInteger)index{
    return [self count] > index;
}

#endif //KLENABLE_EXCEPTION_SWIZZLE



@end
